#pragma once
//============================================================================
// Copyright (C) 2010 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#define MAX_SCORES_IN_STATS_LIST 10 // maximum high scores to keep record of

// high score data to save
class HighScoreInfo
{
public:
	//=== vars ===//
	U32			m_u32PlayTimeMs;		// amount of time taken to finish level
	U32			m_u32UnixDateStamp;	// unix time stamp of when high score was done


	//=== constructor ===//
	HighScoreInfo() 
		: m_u32PlayTimeMs(0) 
		, m_u32UnixDateStamp(0) 
	{ 
		// empty
	}
	//=== constructor ===//
	HighScoreInfo( U32 u32PlayTime, U32 u32UnixDateStamp ) 
		: m_u32PlayTimeMs(u32PlayTime)
		, m_u32UnixDateStamp(u32UnixDateStamp) 
	{ 
		// empty
	}
	//! compare which is better time
	bool operator < (const HighScoreInfo&  oOther ) 
	{
		return m_u32PlayTimeMs < oOther.m_u32PlayTimeMs;
	}

};

// class holding stats for level
class SaveLevelStats
{
public:

	//=== saved vars ===//
	U32					m_u32StatsId;	
	irr::core::stringc	m_strLevelName;		// level name as string
	S32					m_s32Difficulty;	// level difficulty
	U32					m_bUnlocked;		// if true level has been unlocked
	U32					m_u32PlayTimeMs;	// number of milliseconds played
	U32					m_u32WinCount;		// number of times user has won the level
	U32					m_u32LoseCount;		// number of times user has lost the level
	U32					m_u32LoadCount;		// number of times level has been started
	irr::core::array<HighScoreInfo> m_aoHighScores; // high scores for this level

	//=== NOT saved vars ===//
	U32					m_u32MinPlayTime;			// minimum amount of time taken to finish level ( in milliseconds )
	U32					m_u32HighScoreTimeStamp;	// unix time stamp of when high score was done

	//=== constructor ===//
	SaveLevelStats() 
		: m_u32StatsId(0)
		, m_s32Difficulty(0)
		, m_bUnlocked(0)
		, m_u32PlayTimeMs(0) 
		, m_u32LoseCount(0)
		, m_u32WinCount(0)
		, m_u32LoadCount(0)
		, m_u32MinPlayTime(0)
		, m_u32HighScoreTimeStamp(0)
	{ 
		// empty
	}
};

class DtwSave 
{
public:
	//=== vars ===//
	// Paths
	irr::core::stringc							m_strRootPath;
	irr::core::stringc							m_strSavesPath;
	irr::core::stringc							m_strScreenshotsPath;
	irr::core::stringc							m_strConfigFile;
	irr::core::stringc							m_strStatsFile;
	// database
	DtwDatabase *								m_poDatabase;
	U32											m_s32DatabaseVersion;
	// level data
	std::map<irr::core::stringc, SaveLevelStats> m_aoLevelStats;
	std::map<irr::core::stringc, SaveLevelStats>::iterator LevelStatsIterator;

	//=== methods ===//
	//! startup with root directory of where to save databases and files
	RCODE	Startup( const char * pSaveRootDir );
	//! shutdown
	void	Shutdown( void );
	//! root directory to save directories
	void	GetRootPath( irr::core::stringc& strRetPath ) { strRetPath = m_strRootPath; }

	//! loads all level stats from database
	RCODE	LoadLevelStatsFromDb( void );
	//! save level stats for the given level
	void	SaveLevelStatsToDb(  irr::core::stringc& strLevel );
	//! update level stats for the given level
	void	UpdateLevelStats(  irr::core::stringc& strLevelName,  SaveLevelStats& oLevelStats );
	//! get level stats for the given level
	RCODE	GetLevelStats(	 irr::core::stringc& strLevelName, SaveLevelStats& oRetLevelStats );
	//! get a pointer level stats for the given level
	const SaveLevelStats * GetLevelStats(  irr::core::stringc& strLevelName );

	//! add a score for this level 
	void	AddScore(  irr::core::stringc& strLevelName, U32 u32PlayTimeMs );
	//! add to count of times user loaded the level
	void	IncrementLevelLoadCount(  irr::core::stringc& strLevelName );
	//! add to count of times user lost the level
	void	IncrementLevelLoseCount(  irr::core::stringc& strLevelName );
	//! add to count of times user won the level
	void	IncrementLevelWinCount(  irr::core::stringc& strLevelName );
	//! add to level play time
	void	IncrementLevelPlayTime(  irr::core::stringc& strLevelName, U32 u32PlayTimeMs );
	//! unlock level
	void	UnlockLevel(  irr::core::stringc& strLevelName );
};

extern DtwSave g_SaveImp;
